"use strict"
function FTPSession(host, port) {
  this.host = host;
  this.port = port;
  this.clientsPool = [];
  this.pendingDownloads = [];
}

FTPSession.prototype.login = function(username, password) {
  this.username = username;
  this.password = password;
  this.generalClient = new FTPClient();
  var self = this;
  return self.generalClient.connect(self.host, self.port).then(function (welcomeMsg) {
    return self.generalClient.login(self.username, self.password);
  }).catch(function (error) {
    throw error;
  });
};

FTPSession.prototype.changeWorkingDir = function(pathname) {
  return this.generalClient.changeWorkingDir(pathname).catch(function (error) {
    throw error;
  });
};

FTPSession.prototype.changeToParentDir = function() {
  return this.generalClient.changeToParentDir().catch(function (error) {
    throw error;
  });
};

FTPSession.prototype.getCurrentDir = function() {
  return this.generalClient.getCurrentDir().catch(function (error) {
    throw error;
  });
};


FTPSession.getRemoteDirEntriesInfo = function(dirPath) {
  return FTPSession.listDir(dirPath).then(function (directoryListing) {
     return FTPUtils.parseLsDirectoryListing(directoryListing);
  });
};

function flatten(a) {
  if (!(a instanceof Array)){
    return [a];
  }
  else {
    var flattenedList = [];
    for (var i = 0; i < a.length; i++) {
      var result = flatten(a[i]);
      flattenedList = flattenedList.concat(result);
    }
    return flattenedList;
  }
}

FTPSession.prototype.createClient = function () {
  var client = new FTPClient();
  var self = this;
  return client.connect(self.host, self.port).then(function (welcomeMsg) {
    return client.login(self.username, self.password);
  }).then(function (reply) {
    return client;
  }).catch(function (error) {
    throw error; // created the cap number of clients the server allowed 
  });

};

FTPSession.prototype.createFTPClientPool = function(requestedClients, onComplete) {
  console.log("CREATE FTP CLIENT POOL", requestedClients);
  var maxClients = 5;
  var self = this;
  if (requestedClients > maxClients) {
    requestedClients = maxClients;
  }
  self.createClient().then(function (client) {
    self.clientsPool.push(client);
    if (self.clientsPool.length < requestedClients) {
      self.createFTPClientPool(requestedClients, onComplete);
    }
    else {
      onComplete();
    }
  }).catch(function(error) {
    FTPUI.notifyUI(error.message);
    onComplete();
  });
};

FTPSession.prototype.downloadFiles = function() {
  var self = this;
  var client = self.clientsPool.shift(), fileInfo = self.pendingDownloads.shift();
  console.log("IN DOWNLOAD FILES", fileInfo);
  var remoteEntry = fileInfo.filePath, localDestination = fileInfo.destination,
      size = fileInfo.size;
  return client.download(remoteEntry, localDestination, size).then(function (reply) {
    console.log("FINISHED DOWNLOAD OF " + remoteEntry, "loging out", reply);
    FTPUI.notifyUI("COMPLETED");
    if (self.pendingDownloads.length > 0) {
      self.clientsPool.push(client);
      self.downloadFiles();
    }
    else {
      client.logOut();
    }
  }).catch(function (error) {
    console.log("Faild on file", remoteEntry, error);
    client.logOut();
    //self.downloadFiles();
    //throw error;
  });
};

FTPSession.prototype.download = function(entryPath, localDestination) {
  console.log("DOWNLOAD CALLED", entryPath.text(), jQuery.data(entryPath, 'size'));
  var self = this;
  if (!FileSystemUtils.isFolder(entryPath)) {
    self.createFTPClientPool(1, function () {
      self.pendingDownloads.push({
        "filePath": jQuery.data(entryPath, 'fullPath'), // a string specifying the full remote path
        "destination": localDestination, // entry object specifying file destination
        "size": jQuery.data(entryPath, 'size')
      });
      self.downloadFiles();
    });
  }
  else {
    FTPUtils.createFoldersAndGetFiles(entryPath, localDestination).then(
      function (filesInfo) {
        filesInfo = flatten(filesInfo);
        self.createFTPClientPool(filesInfo.length, function () {
          self.pendingDownloads = self.pendingDownloads.concat(filesInfo);
          self.downloadFiles();
        });
    });
  }
};

FTPSession.prototype.listDir = function(pathname) {
  var client = new FTPClient();
  var self = this;
  return client.connect(self.host, self.port).then(function (welcomeMsg) {
    return client.login(self.username, self.password);
  }).then(function (reply) {
    return client.listDir(pathname);
  }).then(function (directoryListing) {
    client.logOut();
    return directoryListing[1];
  }).catch(function (error) {
    client.logOut();
    console.log(error);
    throw error;
  });
};

